<?php
/**
 * Fastapp.
 * 3/26/24
 * @Author deepsea
 * @Contact telegram:deepsea159
 */

namespace App\Fastapp\Api\Service\Comm;

use App\Fastapp\Api\Service\BaseService;
use App\Fastapp\Api\Service\Pay\ValidateWithdrawal;
use App\Fastapp\Exception\TipException;
use App\Fastapp\Model\FastappCategory;
use App\Fastapp\Model\FastappTag;
use App\Fastapp\Model\FastappVersion;
use chillerlan\QRCode\Data\QRMatrix;
use chillerlan\QRCode\Output\QROutputInterface;
use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions;
use GuzzleHttp\Client;
use Mine\MineCollection;

class AppService extends BaseService
{
    public function config(): array
    {
        return [
            'site_config' => api_cache()->getConfigByGroupKey('site_config'),
            'business_source' => api_cache()->getDictByKey('business_source'),
            'app_config' => api_cache()->getAppSetting(fastapp_header('account-type', 1)),
            'version' => $this->version(fastapp_header('app-name', 'fastapp')),
            'currency' => get_currency_cache(),
        ];
    }

    public function settingConfig(string $key = 'site_config'): array
    {
        return api_cache()->getConfigByGroupKey($key);
    }

    public function dictData(string $key = 'business_source'): array
    {
        return api_cache()->getDictByKey($key);
    }

    public function version(string $app_name): array
    {
        $md = FastappVersion::query()->select(['version', 'date', 'url', 'content'])
            ->where(['app_name' => $app_name ?: 'app_default'])
            ->orderByDesc('id')->first();
        if (!$md) return [
            'version' => '1.0.0',
            'date' => '2025-02-21',
            'url' => '',
            'content' => 'init'
        ];
        $md->content = fastapp_lang_text($md->content);
        return $md->toArray();
    }

    public function versionList(string $app_name): array
    {
        return ['list' => FastappVersion::query()
            ->select(['version', 'date', 'url', 'content'])
            ->where(['app_name' => $app_name ?: 'default_app'])
            ->orderByDesc('id')->get()->map(function ($item) {
                $item->content = fastapp_lang_text($item->content);
                return $item;
            })];
    }

    public function genQrcode(array|string $data): string
    {
        if (empty($data)) throw new TipException(fastapp_t('fastapp.invalid_parameter'));
        $options = new QROptions;
        $options->outputType = QROutputInterface::GDIMAGE_PNG;
        $options->quality = 90;
        $options->scale = 10;
        $options->bgColor = [255, 255, 255];
        $options->imageTransparent = true;
        $options->transparencyColor = [255, 255, 255];
        $options->drawCircularModules = true;
        $options->drawLightModules = true;
        $options->circleRadius = 0.4;
        $options->keepAsSquare = [
            QRMatrix::M_FINDER_DARK,
            QRMatrix::M_FINDER_DOT,
            QRMatrix::M_ALIGNMENT_DARK,
        ];
        $options->outputBase64 = false;
        if (is_array($data)) {
            if (empty($data['url'])) $s = json_encode($data, JSON_UNESCAPED_UNICODE);
            else $s = $data['url'];
        } else $s = $data;
        return (new QRCode($options))->render($s);
    }

    public function getGeocoder(array $param): array
    {
        $config = api_cache()->getConfigByGroupKey('tcloud');
        $client = new Client();
        $param['key'] = $config['qq_map_key'];
        $res = $client->get('https://apis.map.qq.com/ws/geocoder/v1', [
            'query' => $param
        ]);
        $data = json_decode($res->getBody()->getContents(), true);
        return $data['result'];
    }

    public function channel(): array
    {
        return redis()->hGetAll('channel') ?: [];
    }

    public function category(): array
    {
        $account_type = fastapp_header('account-type', 0);
        $scene = 1;
        if (str_starts_with($account_type, '7')) $scene = 701;
        $treeData = FastappCategory::query()
            ->select(['id', 'name', 'icon', 'view', 'num', 'parent_id'])
            ->where(['scene' => $scene, 'status' => 1])
            ->orderByDesc('sort')
            ->get()->map(function ($item) {
                $item->name = fastapp_lang_text($item->name);
                return $item;
            });
        $tree = (new MineCollection())->toTree($treeData->toArray());
        return ['tree' => $tree];
    }

    public function categoryByCode(string $code): array
    {
        $account_type = fastapp_header('account-type', 1);
        $scene = 1;
        if (str_starts_with($account_type, '7')) $scene = 701;
        $list = FastappCategory::query()
            ->select(['id', 'name', 'icon', 'view', 'num', 'parent_id'])
            ->where(['scene' => $scene, 'status' => 1, 'code' => $code])
            ->orderByDesc('sort')
            ->get()->map(function ($item) {
                $item->name = fastapp_lang_text($item->name);
                return $item;
            });
        return ['list' => $list];
    }

    public function tag(): array
    {
        $account_type = fastapp_header('account-type', 1);
        $scene = 1;
        if (str_starts_with($account_type, '7')) $scene = 701;
        return ['list' => FastappTag::query()
            ->select(['id', 'name', 'icon', 'view'])
            ->orderByDesc('sort')
            ->where(['scene' => $scene, 'status' => 1])->get()->map(function ($item) {
                $item->name = fastapp_lang_text($item->name);
                return $item;
            })];
    }

    public function withdrawalStatus(): array
    {
        try {
            return ['status' => (int)ValidateWithdrawal::validate(get_uid())];
        } catch (\Throwable) {
        }
        return ['status' => 0];
    }
}